import java.io.*;
import java.net.*;
import java.security.*;
import java.security.cert.*;
import javax.crypto.*;

public class SecureClientServerExample {

    // 客户端和服务器共享的证书存放路径
    private static final String CERTIFICATE_PATH = "certificate.crt";

    // 客户端和服务器共享的密钥库存放路径和密码
    private static final String KEYSTORE_PATH = "keystore.jks";
    private static final String KEYSTORE_PASSWORD = "zhaoleipeng123";

    // 客户端和服务器共享的密钥别名和密码
    private static final String KEY_ALIAS = "key_alias";
    private static final String KEY_PASSWORD = "zhaoleipeng123";

    // 加密算法
    private static final String ENCRYPTION_ALGORITHM = "RSA";

    public static void main(String[] args) {
        // 服务器端的代码示例
        new Thread(new ServerThread()).start();

        // 客户端的代码示例
        try {
            Socket socket = new Socket("localhost", 12345);

            // 客户端需要发送数据前获取服务器的证书进行验证
            X509Certificate serverCert = getCertificate(CERTIFICATE_PATH);
            // 可以进行一些验证，比如验证证书是否受信任等

            // 客户端发送数据的示例
            OutputStream outputStream = socket.getOutputStream();
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(serverCert));
            CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
            cipherOutputStream.write("Hello from client!".getBytes());
            cipherOutputStream.close();

            // 客户端接收数据前获取服务器的证书进行验证
            InputStream inputStream = socket.getInputStream();
            // 可以进行一些验证

            // 客户端接收数据的示例
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String response = reader.readLine();
            System.out.println("Server responded: " + response);

            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 服务器端线程
    static class ServerThread implements Runnable {
        public void run() {
            try {
                ServerSocket serverSocket = new ServerSocket(12345);
                Socket socket = serverSocket.accept();

                // 服务器接收数据前获取客户端的证书进行验证
                InputStream inputStream = socket.getInputStream();
                // 可以进行一些验证

                // 服务器接收数据的示例
                Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
                CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
                BufferedReader reader = new BufferedReader(new InputStreamReader(cipherInputStream));
                String message = reader.readLine();
                System.out.println("Client sent: " + message);

                // 服务器发送数据的示例
                OutputStream outputStream = socket.getOutputStream();
                outputStream.write("Hello from server!".getBytes());

                socket.close();
                serverSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 从文件中加载证书
    private static X509Certificate getCertificate(String path) throws Exception {
        FileInputStream fis = new FileInputStream(path);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);
        fis.close();
        return cert;
    }

    // 获取公钥
    private static PublicKey getPublicKey(X509Certificate certificate) throws Exception {
        return certificate.getPublicKey();
    }

    // 获取私钥
    private static PrivateKey getPrivateKey() throws Exception {
        KeyStore keystore = KeyStore.getInstance("JKS");
        FileInputStream fis = new FileInputStream(KEYSTORE_PATH);
        keystore.load(fis, KEYSTORE_PASSWORD.toCharArray());
        fis.close();
        return (PrivateKey) keystore.getKey(KEY_ALIAS, KEY_PASSWORD.toCharArray());
    }
}